package com.shujia.wyh.day28;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

/*
        通过反射获取Class文件对象中的成员方法并使用
 */
public class ReflexDemo5 {
    public static void main(String[] args) throws Exception {
        //获取Person类的Class文件对象
        Class<?> c1 = Class.forName("com.shujia.wyh.day28.Person");

        //获取方法
        //Method[] getMethods()
        //返回包含一个数组 方法对象反射由此表示的类或接口的所有公共方法 类对象，包括那些由类或接口和那些从超类和超接口继承的声明。
        //获取本类以及父类中所有的公共方法（被public所修饰的方法）
        Method[] methods = c1.getMethods();
        for (Method method : methods) {
            System.out.println(method);
        }
        System.out.println("==========================================");
        //获取本类中的所有方法，包括私有的，被保护的，默认的，公共的。不获取继承关系父类中的方法
        Method[] declaredMethods = c1.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            System.out.println(declaredMethod);
        }
        System.out.println("===========================================");
        Constructor<?> con1 = c1.getConstructor();
        Object o = con1.newInstance();

        //获取单个方法并使用
        //Object invoke(Object obj, Object... args)
        //在具有指定参数的 方法对象上调用此 方法对象表示的底层方法。
        Method fun1 = c1.getMethod("fun1");
        fun1.invoke(o);
        System.out.println("======================================");
        //获取私有的成员方法并使用
        Method fun2 = c1.getDeclaredMethod("fun2", String.class);
        //暴力访问
        fun2.setAccessible(true);  //只有私有的成员方法通过反射调用的时候，需要暴力访问
        fun2.invoke(o,"你好");
        System.out.println("======================================");
        Method fun3 = c1.getDeclaredMethod("fun3");
        fun3.invoke(o);
        System.out.println("=====================================");
        Method fun4 = c1.getDeclaredMethod("fun4");
        fun4.invoke(o);

    }
}
